package wec_wallet.ebo.com.api.safe.cleanmemory;

import android.app.ActivityManager;
import android.app.Service;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;

import com.jaredrummler.android.processes.AndroidProcesses;

import net.tsz.afinal.FinalDb;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import bassproject.ebo.com.ebobass.utils.Lg;
import wec_wallet.ebo.com.R;
import wec_wallet.ebo.com.api.safe.data.model.AppProcessInfo;
import wec_wallet.ebo.com.api.safe.data.model.Ignore;


/**
 * 清理内存
 */
public class CleanRAMService extends Service {

    private static final String TAG = "CleanerService";


    private ActivityManager activityManager = null;
    private PackageManager packageManager = null;


    private List<AppProcessInfo> list = null;
    private Context mContext;
    private OnProcessActionListener mOnActionListener;


    private ProcessServiceBinder mBinder = new ProcessServiceBinder();

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public void onCreate() {
        mContext = getApplicationContext();

        try {
            activityManager = (ActivityManager) getSystemService(
                    Context.ACTIVITY_SERVICE);
            packageManager = mContext.getPackageManager();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return START_NOT_STICKY;
    }

    public void scanRunProcess() {
        new TaskScan().execute();
    }

    public void killBackgroundProcesses(String processName) {

        String packageName = null;
        try {
            if (processName.indexOf(":") == -1) {
                packageName = processName;
            } else {
                packageName = processName.split(":")[0];
            }

            activityManager.killBackgroundProcesses(packageName);

            //app使用FORCE_STOP_PACKAGES权限，app必须和这个权限的声明者的签名保持一致！
            Method forceStopPackage = activityManager.getClass()
                    .getDeclaredMethod(
                            "forceStopPackage",
                            String.class);
            forceStopPackage.setAccessible(true);
            forceStopPackage.invoke(activityManager, packageName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public long getAvailMemory(Context context) {
        // 获取android当前可用内存大小
        ActivityManager.MemoryInfo memoryInfo
                = new ActivityManager.MemoryInfo();
        activityManager.getMemoryInfo(memoryInfo);
        // 当前系统可用内存 ,将获得的内存大小规格化

        return memoryInfo.availMem;
    }

    public void cleanAllProcess() {
        new TaskClean().execute();
    }

    public void setOnActionListener(OnProcessActionListener listener) {
        mOnActionListener = listener;
    }

    public ApplicationInfo getApplicationInfo(String processName) {
        if (processName == null) {
            return null;
        }
        List<ApplicationInfo> appList = packageManager.getInstalledApplications(
                PackageManager.GET_UNINSTALLED_PACKAGES);
        for (ApplicationInfo appInfo : appList) {
            if (processName.equals(appInfo.processName)) {
                return appInfo;
            }
        }
        return null;
    }


    public interface OnProcessActionListener {
        void onScanStarted(Context context);

        void onScanProgressUpdated(Context context, int current, int max, long memory, String processName);

        void onScanCompleted(Context context, List<AppProcessInfo> apps);

        void onCleanStarted(Context context);

        void onCleanCompleted(Context context, long cacheSize);
    }

    public class ProcessServiceBinder extends Binder {

        public CleanRAMService getService() {
            return CleanRAMService.this;
        }
    }

    private class TaskScan
            extends AsyncTask<Void, Object, List<AppProcessInfo>> {

        private int mAppCount = 0;

        private long mAppMemory = 0;

        private FinalDb mFinalDb = FinalDb.create(mContext);


        @Override
        protected void onPreExecute() {
            if (mOnActionListener != null) {
                mOnActionListener.onScanStarted(CleanRAMService.this);
            }
        }


        @Override
        protected List<AppProcessInfo> doInBackground(Void... params) {
            list = new ArrayList<>();
            ApplicationInfo appInfo = null;
            AppProcessInfo abAppProcessInfo = null;
            //得到所有正在运行的进程


            if (Build.VERSION.SDK_INT >= 24) {

                Calendar calendar = Calendar.getInstance();
                calendar.setTime(new Date());
                long endt = calendar.getTimeInMillis();//结束时间
                calendar.add(Calendar.DAY_OF_MONTH, -1);//时间间隔为一个月
                long statt = calendar.getTimeInMillis();//开始时间
                UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(USAGE_STATS_SERVICE);
                //获取一个月内的信息
                List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_MONTHLY, statt, endt);

                if (queryUsageStats == null || queryUsageStats.isEmpty()) {
                    return null;
                }

                UsageStats recentStats = null;
                for (UsageStats usageStats : queryUsageStats) {

                    if (recentStats == null || recentStats.getLastTimeUsed() < usageStats.getLastTimeUsed()) {
                        recentStats = usageStats;
                    }
                }

//                return recentStats.getPackageName();


            } else {
                List<ActivityManager.RunningAppProcessInfo> appProcessList
                        = AndroidProcesses.getRunningAppProcessInfo(mContext);
                publishProgress(0, appProcessList.size(), 0, "开始扫描");

                for (ActivityManager.RunningAppProcessInfo appProcessInfo : appProcessList) {
                    abAppProcessInfo = new AppProcessInfo(
                            appProcessInfo.processName, appProcessInfo.pid,
                            appProcessInfo.uid);
                    String packName = appProcessInfo.processName;
                    try {
                        appInfo = packageManager.getApplicationInfo(
                                appProcessInfo.processName, 0);

                        if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                            abAppProcessInfo.isSystem = true;
                        } else {
                            abAppProcessInfo.isSystem = false;
                        }
                        Drawable icon = appInfo.loadIcon(packageManager);
                        String appName = appInfo.loadLabel(packageManager)
                                .toString();
                        abAppProcessInfo.icon = icon;
                        abAppProcessInfo.appName = appName;
                        //abAppProcessInfo.packName = packName;
                    } catch (PackageManager.NameNotFoundException e) {
                        abAppProcessInfo.icon = mContext.getResources()
                                .getDrawable(
                                        R.mipmap.ic_launcher);
                        //String packName = appProcessInfo.processName;
                        appInfo = getApplicationInfo(
                                appProcessInfo.processName.split(":")[0]);
                        if (appInfo != null) {
                            Drawable icon = appInfo.loadIcon(packageManager);
                            abAppProcessInfo.icon = icon;
                            packName = appProcessInfo.processName.split(":")[0];
                        }
                        abAppProcessInfo.isSystem = true;
                        abAppProcessInfo.appName = appProcessInfo.processName;
                        //abAppProcessInfo.packName = packName;
                    }
                    abAppProcessInfo.packName = packName;
                    long memory = activityManager.getProcessMemoryInfo(new int[]{
                            appProcessInfo.pid})[0].getTotalPrivateDirty() * 1024;
                    abAppProcessInfo.memory = memory;

                    List<Ignore> ignores = mFinalDb.findAllByWhere(Ignore.class,
                            "packName='" + abAppProcessInfo.packName + "'");
                    // List<Ignore> ignores = mFinalDb.findAll(Ignore.class);
                    if (ignores.size() == 0) {
                        list.add(abAppProcessInfo);
                        mAppMemory += memory;
                        publishProgress(++mAppCount, appProcessList.size(),
                                mAppMemory, abAppProcessInfo.processName);
                    }
                }
            }










            return list;
        }


        @Override
        protected void onProgressUpdate(Object... values) {
            if (mOnActionListener != null) {
                mOnActionListener.onScanProgressUpdated(CleanRAMService.this,
                        Integer.parseInt(values[0] + ""),
                        Integer.parseInt(values[1] + ""),
                        Long.parseLong(values[2] + ""), values[3] + "");
            }
        }


        @Override
        protected void onPostExecute(List<AppProcessInfo> result) {
            if (mOnActionListener != null) {
                mOnActionListener.onScanCompleted(CleanRAMService.this, result);
            }
        }
    }

    private class TaskClean extends AsyncTask<Void, Void, Long> {

        private FinalDb mFinalDb = FinalDb.create(mContext);


        @Override
        protected void onPreExecute() {
            if (mOnActionListener != null) {
                mOnActionListener.onCleanStarted(CleanRAMService.this);
            }
        }


        @Override
        protected Long doInBackground(Void... params) {
            long beforeMemory = 0;
            long endMemory = 0;
            ActivityManager.MemoryInfo memoryInfo
                    = new ActivityManager.MemoryInfo();
            activityManager.getMemoryInfo(memoryInfo);
            beforeMemory = memoryInfo.availMem;
            List<ActivityManager.RunningAppProcessInfo> appProcessList
                    = AndroidProcesses.getRunningAppProcessInfo(mContext);
            ApplicationInfo appInfo = null;
            for (ActivityManager.RunningAppProcessInfo info : appProcessList) {
                String packName = info.processName;
                try {
                    packageManager.getApplicationInfo(info.processName, 0);
                } catch (PackageManager.NameNotFoundException e) {
                    appInfo = getApplicationInfo(
                            info.processName.split(":")[0]);
                    if (appInfo != null) {
                        packName = info.processName.split(":")[0];
                    }
                }
                List<Ignore> ignores = mFinalDb.findAllByWhere(Ignore.class,
                        "packName='" + packName + "'");
                if (ignores.size() == 0) {
                    Lg.d(info.processName);
                    killBackgroundProcesses(info.processName);
                }
            }
            activityManager.getMemoryInfo(memoryInfo);
            endMemory = memoryInfo.availMem;
            return endMemory - beforeMemory;
        }


        @Override
        protected void onPostExecute(Long result) {

            if (mOnActionListener != null) {
                mOnActionListener.onCleanCompleted(CleanRAMService.this, result);
            }
        }
    }
}
